package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.*;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.CTurnoverMapper;
import cn.huiyunche.base.service.mappers.CWaybillMapper;
import cn.huiyunche.base.service.mappers.DWaybillMapper;
import cn.huiyunche.base.service.mappers.SOrderFeedetailMapper;
import cn.huiyunche.base.service.mappers.ext.CTurnoverOrdersViewMapper;
import cn.huiyunche.base.service.mappers.ext.CTurnoverViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.model.view.CTurnoverOrdersViewExample;
import cn.huiyunche.base.service.utils.DateUtils;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.tools.basic.Collections3;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSON;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 账户流水明细接口实现类
 *
 * @author lm
 */
@Service
public class CAccntTurnOverServiceImpl implements CAccntTurnOverService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CAccntTurnOverServiceImpl.class);

    @Autowired
    private UserService userService = null;

    @Autowired
    private CTurnoverMapper cTurnoverMapper = null;

    @Autowired
    private CTurnoverViewMapper cTurnoverViewMapper = null;

    @Autowired
    private CAccntBalanceService accntLedgerService = null;

    @Autowired
    private SOrderService orderService = null;

    @Autowired
    private WaybillBidService waybillBidService = null;

    @Autowired
    private SOrderFeedetailMapper sOrderFeedetailMapper = null;

    @Autowired
    private OrderStatusLogService orderStatusLogService = null;

    @Autowired
    private CWaybillMapper cWaybillMapper = null;

    @Autowired
    private CTurnoverOrdersViewMapper cTurnoverOrdersViewMapper = null;

    @Autowired
    private BScoresService bScoresService = null;

    @Autowired
    private CAccntBillService cAccntBillService = null;

    @Autowired
    private DWaybillMapper dWaybillMapper = null;

    @Autowired
    private DSubSupplierService dSubSupplierService = null;

    private DSubSupplierService getDSubSupplierService() {
        return this.dSubSupplierService;
    }

    private DWaybillMapper getDWaybillMapper() {
        return this.dWaybillMapper;
    }

    private CAccntBillService getCAccntBillService() {
        return this.cAccntBillService;
    }

    private BScoresService getBScoresService() {
        return this.bScoresService;
    }

    private UserService getUserService() {
        return this.userService;
    }

    private CTurnoverMapper getCTurnoverMapper() {
        return this.cTurnoverMapper;
    }

    private CAccntBalanceService getAccntLedgerService() {
        return this.accntLedgerService;
    }

    private CTurnoverViewMapper getcTurnoverViewMapper() {
        return this.cTurnoverViewMapper;
    }

    private SOrderService getOrderService() {
        return this.orderService;
    }

    private OrderStatusLogService getOrderStatusLogService() {
        return this.orderStatusLogService;
    }

    private WaybillBidService getWaybillBidService() {
        return this.waybillBidService;
    }

    private SOrderFeedetailMapper getSOrderFeedetailMapper() {
        return this.sOrderFeedetailMapper;
    }

    private CWaybillMapper getCWaybillMapper() {
        return cWaybillMapper;
    }

    private CTurnoverOrdersViewMapper getCTurnoverOrdersViewMapper() {
        return this.cTurnoverOrdersViewMapper;
    }

    // 查询当前登录用户
    public UserShowVo getUserShowVo() {
        UserShowVo currentUser = null;
        try {
            currentUser = this.getUserService().getCurrentUser();
        } catch (Exception e) {
            LOGGER.info("查询当前登录用户异常.");
            e.printStackTrace();
        }
        return currentUser;
    }

    /**
     * 查询账户流水
     *
     * @param page
     * @return
     */
    @Override
    public Result<Map<String, Object>> getDetails(PageVo page) {
        LOGGER.info("select current user accntDetails params page : {}.", page);
        Result<Map<String, Object>> result = new Result<>(true, "查询成功！");
        Map<String, Object> map = new HashMap<>();
        try {
            // 查询当前用户
            UserShowVo userShowVo = this.getUserShowVo();
            if (null == userShowVo) {
                result.setSuccess(false);
                result.setMessage("当前登录账户不存在!");
                return result;
            }

            Long userId = userShowVo.getId();
            Integer userType = userShowVo.getUserType();
            CTurnoverExample example = new CTurnoverExample();
            if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
                example.createCriteria().andCompanyIdEqualTo(userId).andUserTypeEqualTo(userType);
            } else {
                example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType);
            }
            LOGGER.info("select current user accntDetails userID : {}, userType : {}.", userId, userType);

            page.setTotalRecord(this.getCTurnoverMapper().countByExample(example));
            String orderByClause = StringUtils.isNotBlank(page.getOrder()) == true ? page.getOrder() : "id DESC ";

            example.setOrderByClause(orderByClause);
            example.setLimitStart(page.getStartIndex());
            example.setLimitEnd(page.getPageSize());

            // List<CTurnover> details =
            // this.getCTurnoverMapper().selectByExample(example);
            List<CTurnoverVo> details = this.getcTurnoverViewMapper().selectByExample(example);
            for (CTurnoverVo cTurnoverVo : details) {
                if (userType == UserTypeEnum.COMPANY.getValue() || userType == UserTypeEnum.SCOMPANY.getValue()) {
                    cTurnoverVo.setAccountId(cTurnoverVo.getCompanyId());
                    cTurnoverVo.setAccountName(cTurnoverVo.getCompanyName());
                } else {
                    cTurnoverVo.setAccountId(cTurnoverVo.getUserId());
                    cTurnoverVo.setAccountName(cTurnoverVo.getUserName());
                }
                cTurnoverVo.setOrderPrice(cTurnoverVo.getOrderFee());
                cTurnoverVo.setOrderTotal(cTurnoverVo.getOrderActPay());
                cTurnoverVo.setFeetype(cTurnoverVo.getPayType());
                cTurnoverVo.setStrOrderTotal("¥ " + cTurnoverVo.getOrderActPay());

                LOGGER.info("select current user accntDetails cTurnover : {}.", cTurnoverVo.getId());

                if (cTurnoverVo.getPayType() == AccPaytypeEnum.ORDER.getValue()) {
                    Long orderId = cTurnoverVo.getOrderId();

                    if (cTurnoverVo.getUserType() == UserTypeEnum.DRIVER.getValue()) {
                        CWaybill cWaybill = this.getCWaybillMapper().selectByPrimaryKey(orderId);
                        if (null != cWaybill) {
                            cTurnoverVo.setOrderCode(cWaybill.getWaybillCode());
                        }
                    } else if (cTurnoverVo.getUserType() == UserTypeEnum.SEND_DRIVER.getValue()) {
                        DWaybill dWaybill = this.getDWaybillMapper().selectByPrimaryKey(orderId);
                        if (null != dWaybill) {
                            cTurnoverVo.setOrderCode(dWaybill.getOrderCode());
                        }
                    } else {
                        SOrder order = this.getOrderService().selectByPrimaryKey(orderId);
                        if (null != order) {
                            cTurnoverVo.setOrderCode(order.getOrderCode());
                        }
                    }
                } else {
                    // cTurnoverVo.setOrderCode(cTurnoverVo.getOrderId()+"");
                    cTurnoverVo.setOrderCode("");
                }
            }

            LOGGER.info("select current user accntDetails details : {}.", JSON.toJSONString(details));
            map.put("page", page);
            map.put("details", details);
            result.setData(map);
        } catch (Exception e) {
            LOGGER.error("select current user accntDetails error : {}.", e);
            result.setSuccess(false);
            result.setMessage("系统异常.");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 更新账户流水 更新账户余额
     *
     * @param quickcash 是否是快速提现 0:不是 1:是
     */
    @Override
    public boolean addDetailsAndLedger(List<CTurnover> cTurnovers, Integer quickcash) {
        LOGGER.info("addDetailsAndLedger params : {}, {}", cTurnovers.size(), quickcash);
        boolean flag = false;
        try {
            if (cTurnovers == null || cTurnovers.size() == 0) {
                LOGGER.info("add cturnovers date is null.");
                return false;
            }

            int count = this.getcTurnoverViewMapper().batchInsert(cTurnovers);
            LOGGER.info("add cturnovers date count is {}.", count);

            for (CTurnover cTurnover : cTurnovers) {
                LOGGER.info("add cturnovers date to add balance params userId:{}, userName:{}.", cTurnover.getUserId(),
                        cTurnover.getUserName());
                addLedger(cTurnover, quickcash);
            }
            flag = true;
        } catch (Exception e) {
            LOGGER.info("插入账户数据异常.");
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 生成账单 更新billID 更新账单流水状态 status:20 已出账单
     *
     * @param beginDate
     * @param endDate
     * @param accountId
     * @param userType
     * @param payTypes
     * @param userIdSet
     * @return
     */
    @Override
    public int updateBnoByBillid(Date beginDate, Date endDate, Long userId, int userType, List<Integer> payTypes,
                                 Set<Long> userIdSet, int status) {
        LOGGER.info("updateBnoByBillid params : {}, {}, {}, {}, {}, {}", beginDate, endDate, userId, userType, payTypes,
                userIdSet, status);
        return this.getcTurnoverViewMapper().updateBnoByBillid(beginDate, endDate, userId, userType, payTypes,
                userIdSet, status);
    }

    @Override
    public int updateBnoByCompanyBillid(Date beginDate, Date endDate, Long userId, int userType, List<Integer> payTypes,
                                        int status) {
        LOGGER.info("updateBnoByCompanyBillid params : {}, {}, {}, {}, {}, {}", beginDate, endDate, userId, userType,
                payTypes, status);
        return this.getcTurnoverViewMapper().updateBnoByCompanyBillid(beginDate, endDate, userId, userType, payTypes,
                status);
    }

    /**
     * 生成账单 更新billID 更新账单流水状态 status:20 已出账单
     *
     * @param beginDate
     * @param endDate
     * @param accountId
     * @param userType
     * @param payTypes
     * @param userIdSet
     * @param status
     * @return
     */
    @Override
    public int updateBnoByBillidNoUser(Date beginDate, Date endDate, Long userId, int userType, List<Integer> payTypes,
                                       Set<Long> userIdSet, int status) {
        LOGGER.info("updateBnoByBillidNoUser params : {}, {}, {}, {}, {}, {}, {}", beginDate, endDate, userId, userType,
                payTypes, userIdSet, status);
        return this.getcTurnoverViewMapper().updateBnoByBillidNoUser(beginDate, endDate, userId, userType, payTypes,
                userIdSet, status);
    }

    /**
     * 订单完成－给司机账户加钱
     *
     * @param orderid
     * @return
     */
    @Override
    public boolean addOrderAmount(long orderId) {
        LOGGER.info("addOrderAmount param : {}", orderId);
        Date currentTime = new Date();
        try {
            SOrder order = this.getOrderService().selectByPrimaryKey(orderId);
            if (null == order) {
                throw new BusinessException(
                        "order finish to add driver accnt balance order is null params orderId : " + orderId);
            }
            Integer status = order.getStatus();
            Integer payStatus = order.getPayStatus();
            LOGGER.info("order finish to add driver accnt balance orderid:{}, status:{}, payStatus:{}.", orderId,
                    status, payStatus);
            List<CTurnover> accntDetails = new ArrayList<>();

			/*
             * if(status == OrderStatusEnum.INTRANSIT.getValue() && payStatus ==
			 * PaymentStatusEnum.ALREADY_PAID.getValue()){ CTurnover cTurnover =
			 * this.addAccountAmount(status, payStatus, orderId); // 发车
			 * 打款运费80%到司机账户
			 * cTurnover.setOrderActPay(cTurnover.getOrderActPay().multiply(new
			 * BigDecimal("0.8"))); log.info("打款80%到司机账户.金额:{}.订单:{}",
			 * cTurnover.getOrderActPay().multiply(new BigDecimal("0.8")),
			 * orderId); accntDetails.add(cTurnover);
			 * this.getOrderStatusLogService().insertSelective(orderId,
			 * cTurnover.getUserId(), cTurnover.getUserName(),
			 * StatusCategoryEnum.PAY, PaymentStatusEnum.ALREADY_PAID); } else
			 */
            if (status == SServiceOrderStatusEnum.DONE.getValue()
                    && payStatus == PaymentStatusEnum.ALREADY_PAID.getValue()) {
                // 查询cTurnover
                CTurnover cTurnover = this.addAccountAmount(status, payStatus, orderId);
                // 发车 打款运费20%到司机账户 -- 去掉
                // cTurnover.setOrderActPay(cTurnover.getOrderActPay().multiply(new
                // BigDecimal("0.2")));
                LOGGER.info("order finish to add driver accnt balance actpay : {}, orderID : {}.",
                        cTurnover.getOrderActPay(), orderId);
                accntDetails.add(cTurnover);

                this.getOrderStatusLogService().insertSelective(orderId, cTurnover.getUserId(), cTurnover.getUserName(),
                        StatusCategoryEnum.PAY, PaymentStatusEnum.ALREADY_PAID);

                // 修改 承运端 运单表支付状态
                CWaybillExample sWaybillExample = new CWaybillExample();
                sWaybillExample.createCriteria().andOrderIdEqualTo(orderId);
                CWaybill sWaybill = this.getCWaybillMapper().selectByExample(sWaybillExample).get(0);
                sWaybill.setPayStatus(PaymentStatusEnum.ALREADY_PAID.getValue());
                this.getCWaybillMapper().updateByPrimaryKey(sWaybill);

                // 添加托运人的信息
                SUser payUser = userService.getById(order.getUserId());
                CTurnover payCTurnover = new CTurnover();

                payCTurnover.setUserId(payUser.getId());
                payCTurnover.setUserName(payUser.getPhone());
                payCTurnover.setUserType(payUser.getUserType());
                payCTurnover.setPayType(AccPaytypeEnum.ORDER.getValue());
                payCTurnover.setOrderId(orderId);
                payCTurnover.setOrderFee(order.getOrderCost());
                payCTurnover.setOrderActPay(order.getOrderCost());
                payCTurnover.setCreateTime(currentTime);
                payCTurnover.setUpdateTime(currentTime);

                LOGGER.info("order finish to add driver accnt balance driverId : {}, orderId : {}.", payUser.getId(),
                        orderId);
                accntDetails.add(payCTurnover);
            }
            return this.addDetailsAndLedger(accntDetails, 0);
        } catch (Exception e) {
            LOGGER.error("order finish to add driver accnt balance error : {}.", e);
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 查询订单已支付司机金额和未支付司机金额
     *
     * @param userId
     * @param orderId
     * @return
     */
    @Override
    public Map<String, BigDecimal> selectDriverOrderAmount(Long userId, Long orderId) {
        LOGGER.info("查询订单已支付司机金额和未支付司机金额.userId:{}, orderId:{}.", userId, orderId);
        Map<String, BigDecimal> maps = new HashMap<String, BigDecimal>();
        BigDecimal orderPaid = BigDecimal.ZERO.setScale(2);
        BigDecimal orderWillPay = BigDecimal.ZERO.setScale(2);
        try {
            SUser user = this.getUserService().selectByPrimaryKey(userId);
            SOrder order = this.getOrderService().selectByPrimaryKey(orderId);
            if (user != null && user.getUserType() == UserTypeEnum.DRIVER.getValue()) {
                List<CTurnover> lists = this.getcTurnoverViewMapper().selectByUserIdAndOrderId(userId, orderId);
                for (CTurnover cTurnover : lists) {
                    orderPaid.add(cTurnover.getOrderActPay().setScale(2, BigDecimal.ROUND_UP));
                }
                orderWillPay = order.getOrderCost().subtract(orderPaid).setScale(2, BigDecimal.ROUND_UP);
            }
            maps.put("paid", orderPaid);
            maps.put("unpaid", orderWillPay);
        } catch (Exception e) {
            LOGGER.info("查询订单已支付司机金额和未支付司机金额系统异常.userId:{}, orderId:{}.", userId, orderId);
            e.printStackTrace();
        }
        return maps;
    }

    /**
     * 查询cTurnover
     *
     * @param status
     * @param payStatus
     * @param orderId
     * @return
     */
    private CTurnover addAccountAmount(int status, int payStatus, long orderId) {
        Date currentTime = new Date();
        LOGGER.info("修改司机账户.orderId:{}, status:{}, payStatus:{}.", orderId, status, payStatus);
        CTurnover cTurnover = new CTurnover();
        try {
            CWaybillBid cWaybillBid = this.getWaybillBidService().selectByOrderid(orderId);
            // 判断竞单类型是 个人接单
            if (cWaybillBid != null && cWaybillBid.getBidderType() == GrabWaybillTypeEnum.GRAB_BY_SELF.getValue()) {
                Long actDriverId = cWaybillBid.getActDriver();

                SUser driverUser = userService.getById(actDriverId);
                LOGGER.info("订单对应的司机:{}.orderId:{}", driverUser.getId(), orderId);

                // 查询订单费用明细 运费明细
                SOrderFeedetailExample example = new SOrderFeedetailExample();
                // example.createCriteria().andOrderIdEqualTo(orderId).andFeeCodeEqualTo(10);
                SOrderFeedetail sOrderFeedetail = this.getSOrderFeedetailMapper().selectByExample(example).get(0);
                BigDecimal money = sOrderFeedetail.getMoney();

                cTurnover.setUserId(driverUser.getId());
                cTurnover.setUserName(driverUser.getRealName());
                cTurnover.setUserType(driverUser.getUserType());
                cTurnover.setPayType(AccPaytypeEnum.ORDER.getValue());
                cTurnover.setOrderId(orderId);
                cTurnover.setOrderFee(money);
                cTurnover.setOrderActPay(money);
                cTurnover.setCreateTime(currentTime);
                cTurnover.setUpdateTime(currentTime);
            }
			/*
			 * SWaybillQuote quote =
			 * this.getWaybillQuoteService().selectQuoteByOrderId(orderId);
			 * log.info("根据orderId查询已选中的报价明细表.orderId:{}, quote:{}.", orderId,
			 * quote.getId());
			 * 
			 * SUser driverUser = userService.getById(quote.getUserId());
			 * log.info("订单对应的司机:{}.orderId:{}", driverUser.getId(), orderId);
			 */

			/*
			 * SQuoteDetailExample example = new SQuoteDetailExample();
			 * example.createCriteria().andOrderIdEqualTo(orderId).
			 * andQuoteIdEqualTo(quote.getId()).andFeeCodeEqualTo(10);
			 * List<SQuoteDetail> sQuoteDetail =
			 * this.getSQuoteDetailMapper().selectByExample(example);
			 * log.info("报价明细表中查询运单报价:{}.orderId:{}",
			 * sQuoteDetail.get(0).getId(), orderId);
			 */
        } catch (Exception e) {
            LOGGER.error("账户余额变更,查询司机报价信息异常.", e);
            // throw new BusinessException("账户余额变更,查询司机报价信息异常.");
            e.printStackTrace();
        }
        return cTurnover;
    }

    /**
     * 更新账户余额，只有司机更新 1，运单完成 2，司机提现／提现失败
     *
     * @param cTurnover
     * @param quickcash 是否是快速提现 0:不是 1:是
     */
    private void addLedger(CTurnover cTurnover, Integer quickcash) {
        Date currentTime = new Date();
        try {
            LOGGER.info("update cBalance params: {}, {}", cTurnover, quickcash);
            Long userId = cTurnover.getUserId();
            Integer userType = cTurnover.getUserType();
            BigDecimal orderActPay = cTurnover.getOrderActPay();
            BigDecimal orderFee = cTurnover.getOrderFee();

            CBalance cBalance = new CBalance();
            if (userType == UserTypeEnum.DRIVER.getValue() || userType == UserTypeEnum.SEND_DRIVER.getValue()) {
                cBalance.setUserId(userId);
                cBalance.setUserName(cTurnover.getUserName());
                cBalance.setUserType(userType);
                cBalance.setBalance(orderActPay);
                LOGGER.info("update cBalance params userId : {}, userType : {}, balance: {}.", userId, userType,
                        orderActPay);
                if (cTurnover.getPayType() == AccPaytypeEnum.WITHDRAWAL.getValue() || cTurnover.getPayType() == AccPaytypeEnum.REWARD.getValue()
                        || cTurnover.getPayType() == AccPaytypeEnum.PUNISH.getValue()) {
                    // if(quickcash == 1){// 是快速提现更新 账户余额 同时更新可提现金额
                    cBalance.setWithdrawalBalance(orderFee);
                    cBalance.setBalance(orderFee);
                    // } else{
                    // 普通提现 只修改可提现金额
                    // cBalance.setWithdrawalBalance(orderActPay);
                    // cBalance.setBalance(orderActPay);
                    // }
                }

                cBalance.setCreateTime(currentTime);
                cBalance.setUpdateTime(currentTime);
                this.getAccntLedgerService().insertOrUpdateRecord(cBalance);
            }
        } catch (Exception e) {
            LOGGER.error("update cBalance error :{} ", e);
            e.printStackTrace();
        }
    }

    @Override
    public Map<String, Object> getKyleBussDetails(PageVo page, List<Long> billIds) {
        LOGGER.info("select kylebuss details serviceimpl params page:{}, billIds:{}.", page, billIds);
        Map<String, Object> map = new HashMap<>();
        List<CTurnoverOrdersVo> cTurnovers = new ArrayList<CTurnoverOrdersVo>();
        try {
            CTurnoverOrdersViewExample example = new CTurnoverOrdersViewExample();
            example.setLimitStart(page.getStartIndex());
            example.setLimitEnd(page.getPageSize());
            if (StringUtils.isNotBlank(page.getOrder())) {
                example.setOrderByClause(page.getOrder());
            } else {
                example.setOrderByClause("id DESC");
            }

            LOGGER.info("select details serviceimpl params copy.");
            if (CollectionUtils.isNotEmpty(billIds)) {
                example.createCriteria().andBillIdIn(billIds);
            }

            page.setTotalRecord(this.getCTurnoverOrdersViewMapper().countByExample(example));
            LOGGER.info("select details serviceimpl mapper.");
            cTurnovers = this.getCTurnoverOrdersViewMapper().selectByExample(example);

            map.put("page", page);
            map.put("cTurnovers", cTurnovers);
        } catch (Exception e) {
            LOGGER.error("select kylebuss details serviceimpl params page:{}, billIds:{}, error:{}.", page, billIds, e);
            throw new BusinessException("查询账单明细异常");
        }
        return map;
    }

    /**
     * 查询流水明细
     */
    @Override
    public Map<String, Object> getDetails(PageVo page, CTurnover cTurnover, BigDecimal amount, BigDecimal usedAmount,
                                          int billStatus) {
        LOGGER.info("select details serviceimpl params page:{}, cTurnover:{}, {}", page, cTurnover, amount);
        Map<String, Object> map = new HashMap<String, Object>();
        List<CTurnoverOrdersVo> cTurnovers = new ArrayList<CTurnoverOrdersVo>();
        try {
            CTurnoverOrdersViewExample example = new CTurnoverOrdersViewExample();
            example.setLimitStart(page.getStartIndex());
            example.setLimitEnd(page.getPageSize());
            if (StringUtils.isNotBlank(page.getOrder())) {
                example.setOrderByClause(page.getOrder());
            } else {
                example.setOrderByClause("id DESC");
            }

            LOGGER.info("select details serviceimpl params copy.");
            if (cTurnover.getBillId() != null && cTurnover.getBillId() != 0L) {
                example.createCriteria().andBillIdEqualTo(cTurnover.getBillId());
            }

            page.setTotalRecord(this.getCTurnoverOrdersViewMapper().countByExample(example));
            LOGGER.info("select details serviceimpl mapper.");
            cTurnovers = this.getCTurnoverOrdersViewMapper().selectByExample(example);

            // 查询明细的时候 查询本月账单可用积分抵扣金额
            QueryKyleBillScoresVo scoresVo = new QueryKyleBillScoresVo();
            if (null != amount) {
                scoresVo = this.getBScoresService().selectKyleCompanyBillScores(amount.abs(), usedAmount);
            }

            if (cTurnover.getBillId() != null && cTurnover.getBillId() != 0L) {
                CBill cBill = this.getCAccntBillService().selectByPrimaryKey(cTurnover.getBillId());
                if (cBill != null) {
                    Integer status = cBill.getStatus();
                    if (status == AccBillStatusEnum.WAIT.getValue()) {
                        scoresVo.setBillStatusShow(1);
                    } else {
                        scoresVo.setBillStatusShow(0);
                    }

                    BigDecimal scoresPaid = cBill.getScoresPaid();
                    if (null == scoresPaid) {
                        scoresPaid = BigDecimal.ZERO;
                    }
                    if (scoresPaid.compareTo(BigDecimal.ZERO) == 1) {
                        scoresVo.setIsUserScores(1);
                    } else {
                        scoresVo.setIsUserScores(0);
                    }
                    scoresVo.setScoresPaid(scoresPaid);
                    scoresVo.setActualPaid(
                            cBill.getAmount().abs().subtract(scoresPaid.abs()).setScale(2, BigDecimal.ROUND_UP));
                }
            } else {
                scoresVo.setIsUserScores(0);
            }

            if (0 != billStatus) {
                scoresVo.setBillstatus(billStatus);
            } else {
                scoresVo.setBillstatus(AccBillStatusEnum.WAIT.getValue());
            }

            map.put("page", page);
            // if(!Collections.isEmpty(cTurnovers)){
            map.put("cTurnovers", cTurnovers);
            map.put("scoresVo", scoresVo);
            return map;
            // }
        } catch (Exception e) {
            LOGGER.error("select details error : {}.", e);
            throw new BusinessException("查询账单明细异常");
        }
        // map.put("page", page);
        // map.put("cTurnovers", cTurnovers);
        // map.put("scoresVo", null);
        // return map;
    }

    /**
     * 判断提现每天每人不能超过3次
     *
     * @param userId
     * @param userType
     * @return
     */
    public Result<Object> valWithdrawalLe3(BigDecimal amount, Long userId, Integer userType) {
        Result<Object> r = new Result<>(true, "验证通过");
        LOGGER.info("val WithdrawalLe3 userId : {}, userType : {}.", userId, userType);
        try {
            CTurnoverExample example = new CTurnoverExample();
            example.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType)
                    .andPayTypeEqualTo(AccPaytypeEnum.WITHDRAWAL.getValue())
                    .andCreateTimeGreaterThanOrEqualTo(DateUtils.getCurrent00ZeroDate())
                    .andCreateTimeLessThanOrEqualTo(DateUtils.getCurrent23ZeroDate())
                    .andOrderActPayGreaterThan(BigDecimal.ZERO);
            List<CTurnover> exampGe0 = this.getCTurnoverMapper().selectByExample(example);

            CTurnoverExample example2 = new CTurnoverExample();
            example2.createCriteria().andUserIdEqualTo(userId).andUserTypeEqualTo(userType)
                    .andPayTypeEqualTo(AccPaytypeEnum.WITHDRAWAL.getValue())
                    .andCreateTimeGreaterThanOrEqualTo(DateUtils.getCurrent00ZeroDate())
                    .andCreateTimeLessThanOrEqualTo(DateUtils.getCurrent23ZeroDate())
                    .andOrderActPayLessThan(BigDecimal.ZERO);
            List<CTurnover> exampLe0 = this.getCTurnoverMapper().selectByExample(example2);

            int le0Size = 0;
            int ge0Size = 0;
            BigDecimal le0Amount = BigDecimal.ZERO;
            BigDecimal ge0Amount = BigDecimal.ZERO;
            if (Collections3.isNotEmpty(exampLe0)) {
                le0Size = exampLe0.size();
                for (CTurnover cTurnover : exampLe0) {
                    le0Amount = le0Amount.add(cTurnover.getOrderActPay().abs());
                }
            }
            if (Collections3.isNotEmpty(exampGe0)) {
                ge0Size = exampGe0.size();
                for (CTurnover cTurnover : exampGe0) {
                    ge0Amount = ge0Amount.add(cTurnover.getOrderActPay().abs());
                }
            }
            if (le0Size - ge0Size >= 3) {
                LOGGER.info("val WithdrawalLe3 userId : {}, userType : {}, withdraw Ge 3.", userId, userType);
                r.setSuccess(false);
                r.setMessage("提现次数超过3次");
            } else if (amount.add(le0Amount).subtract(ge0Amount).compareTo(BigDecimal.valueOf(20000)) == 1) {
                r.setSuccess(false);
                r.setMessage("当前提现限额为2万");
            }
        } catch (Exception e) {
            LOGGER.error("val WithdrawalLe3 userId : {}, userType : {}, error : {}.", userId, userType, e);
            throw new BusinessException("判断用户每日提现不能超过3次异常");
        }
        return r;
    }

    @Override
    public Result<Map<String, Object>> getDriver3rdDetailsGroupMonth(PageVo page) {
        LOGGER.info("select current user group by month parms page : {}.", page);
        Result<Map<String, Object>> result = new Result<>(true, "查询成功");
        Map<String, Object> resultMap = new LinkedHashMap<>();
        try {
            UserShowVo user = this.getUserShowVo();

            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("companyId", user.getId());
            paramsMap.put("userType", user.getUserType());

            paramsMap.put("limitStart", page.getStartIndex());
            paramsMap.put("limitEnd", page.getPageSize());
            if (StringUtils.isNotBlank(page.getOrder())) {
                paramsMap.put("orderByClause", page.getOrder());
            } else {
                paramsMap.put("orderByClause", " id DESC");
            }

            CTurnover3rdVo cTurnover3rdVo = new CTurnover3rdVo();
            page.setTotalRecord(this.getcTurnoverViewMapper().countDWaybillByExample(paramsMap));
            List<CTurnoverDWaybillVo> list = this.getcTurnoverViewMapper().selectDWaybillByExample(paramsMap);
            List<CTurnover3rdVo> newList = new ArrayList<>();
            for (CTurnoverDWaybillVo cTurnoverDWaybillVo : list) {
                BeanUtils.copyProperties(cTurnover3rdVo, cTurnoverDWaybillVo);
                Long waybillId = cTurnoverDWaybillVo.getOrderId();
                List<DWaybillPriceDetailVo> priceList = this.getDSubSupplierService().selectPriceById(waybillId);
                cTurnover3rdVo.setPriceVo(priceList);
                newList.add(cTurnover3rdVo);
            }

            resultMap.put("page", page);
            resultMap.put("details", newList);
            result.setData(resultMap);
            return result;
        } catch (Exception e) {
            LOGGER.error("select current user group by month parms page : {}, error : {}.", page, e);
            throw new BusinessException("查询我的账单异常");
        }
    }

    @Override
    public Result<Map<String, Object>> getDetailsGroupMonth(PageVo page) {
        LOGGER.info("select current user group by month parms page : {}.", page);
        Result<Map<String, Object>> result = new Result<>(true, "查询成功");
        Map<String, Object> resultMap = new LinkedHashMap<>();
        try {
            UserShowVo user = this.getUserShowVo();

            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("userId", user.getId());
            paramsMap.put("userType", user.getUserType());

            paramsMap.put("limitStart", page.getStartIndex());
            paramsMap.put("limitEnd", page.getPageSize());
            if (StringUtils.isNotBlank(page.getOrder())) {
                paramsMap.put("orderByClause", page.getOrder());
            } else {
                paramsMap.put("orderByClause", " id DESC");
            }

            page.setTotalRecord(this.getcTurnoverViewMapper().countDWaybillByExample(paramsMap));
            // List<CTurnover> list =
            // this.getCTurnoverMapper().selectByExample(example);
            List<CTurnoverDWaybillVo> list = this.getcTurnoverViewMapper().selectDWaybillByExample(paramsMap);

            List<Map<String, Object>> resultList = new ArrayList<>();
            for (CTurnoverDWaybillVo cTurnover : list) {
                Date createTime = cTurnover.getCreateTime();
                Calendar ca = Calendar.getInstance();
                ca.setTime(createTime);
                int month = ca.get(Calendar.MONTH) + 1;

                List<String> months = new ArrayList<>();
                for (Map<String, Object> map3 : resultList) {
                    String oldMonth2 = (String) map3.get("month");
                    months.add(oldMonth2);
                }
                if (months.contains(ca.get(Calendar.YEAR) + "年" + month + "月")) {
                    for (Map<String, Object> map2 : resultList) {
                        String oldMonth = (String) map2.get("month");
                        if (oldMonth.equals(ca.get(Calendar.YEAR) + "年" + month + "月")) {
                            @SuppressWarnings("unchecked")
                            List<CTurnoverDWaybillVo> values = (List<CTurnoverDWaybillVo>) map2.get("list");
                            values.add(cTurnover);
                        }
                    }
                } else {
                    List<CTurnoverDWaybillVo> newList = new ArrayList<>();
                    Map<String, Object> map = new HashMap<>();
                    newList.add(cTurnover);
                    map.put("month", ca.get(Calendar.YEAR) + "年" + month + "月");
                    map.put("list", newList);

                    resultList.add(map);
                }

            }

            resultMap.put("page", page);
            resultMap.put("details", resultList);

            result.setData(resultMap);
            return result;
        } catch (Exception e) {
            LOGGER.error("select current user group by month error : {}.", e);
            throw new BusinessException("查询账户月区分流水异常");
        }
    }

    @Override
    public boolean addSendByDriverCost(Long waybillId, BigDecimal confirmTotalCost, Long userId) {
        LOGGER.info("add send by driver cost waybillId : {}, confirmTotalCost : {], userId : {}.", waybillId,
                confirmTotalCost, userId);
        try {
            // 添加结算唯一性校验 2016-12-05 14:54:35
            // author hdy[Tuffy]
            // ----开始----
            CTurnoverExample cte = new CTurnoverExample();
            cte.createCriteria().andOrderIdEqualTo(waybillId).andPayTypeEqualTo(AccPaytypeEnum.ORDER.getValue())
                    .andUserTypeEqualTo(UserTypeEnum.SEND_DRIVER.getValue());
            List<CTurnover> clist = this.cTurnoverMapper.selectByExample(cte);
            if (clist.size() > 0) {
                return false;
            }
            // ----结束----
            SUser user = this.getUserService().selectByPrimaryKey(userId);
            CTurnover turnover = new CTurnover();

            if (null == confirmTotalCost || BigDecimal.ZERO.compareTo(confirmTotalCost) == 0) {
                DWaybill dWaybill = this.getDWaybillMapper().selectByPrimaryKey(waybillId);
                if (null != dWaybill) {
                    confirmTotalCost = dWaybill.getConfirmTotalCost();
                }
            }
            turnover.setOrderActPay(confirmTotalCost);
            turnover.setOrderFee(confirmTotalCost);

            turnover.setCreateTime(new Date());
            turnover.setUpdateTime(new Date());
            turnover.setOrderId(waybillId);
            turnover.setStatus(AccTurnoverStatusEnum.DONE.getValue());
            turnover.setPayType(AccPaytypeEnum.ORDER.getValue());
            turnover.setUserId(user.getId());
            turnover.setUserType(UserTypeEnum.SEND_DRIVER.getValue());
            turnover.setUserName(user.getRealName());

            List<CTurnover> list = new ArrayList<>();
            list.add(turnover);

            this.addDetailsAndLedger(list, 0);
            return true;
        } catch (Exception e) {
            LOGGER.error("add send by driver cost error : {}.", e);
            throw new BusinessException("人送车项目添加司机账户余额异常");
        }
    }

    @Override
    public Map<String, Object> getsendByDriverDetails(PageVo page, CTurnoverAdminVo cTurnover) {
        try {
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("limitStart", page.getStartIndex());
            paramsMap.put("limitEnd", page.getPageSize());
            if (StringUtils.isNotBlank(page.getOrder())) {
                paramsMap.put("orderByClause", page.getOrder());
            } else {
                paramsMap.put("orderByClause", " t.id DESC");
            }

            paramsMap.put("billId", cTurnover.getBillId());

            page.setTotalRecord(this.getcTurnoverViewMapper().countByConditions(paramsMap));
            List<CTurnoverAdminVo> list = this.getcTurnoverViewMapper().selectByConditions(paramsMap);

            Map<String, Object> map = new HashMap<>();
            map.put("page", page);
            map.put("cTurnovers", list);
            return map;
        } catch (Exception e) {
            LOGGER.error("select send by driver details error : {}.", e);
            throw new BusinessException("查询账单流水异常");
        }
    }

    @Override
    public Map<String, Object> selectVeneerDetails(PageVo page, Long billid) {
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("limitStart", page.getStartIndex());
        paramsMap.put("limitEnd", page.getPageSize());
        if (StringUtils.isNotEmpty(page.getOrder())) {
            paramsMap.put("orderByClause", page.getOrder());
        } else {
            paramsMap.put("orderByClause", " w.id DESC");
        }

        paramsMap.put("billId", billid);

        page.setTotalRecord(this.getcTurnoverViewMapper().countVeneerDetails(paramsMap));
        List<CTurnoverVeneerVo> list = this.getcTurnoverViewMapper().selectVeneerDetails(paramsMap);
        for (CTurnoverVeneerVo cTurnoverVeneerVo : list) {
            String branbVehicleshow = "";
            List<String> branbVehicles = cTurnoverVeneerVo.getBranbVehicles();
            if (CollectionUtils.isNotEmpty(branbVehicles)) {
                for (String string : branbVehicles) {
                    branbVehicleshow = branbVehicleshow.concat(" " + string);
                }
            }
            cTurnoverVeneerVo.setDetail(branbVehicleshow);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("page", page);
        map.put("details", list);
        return map;
    }

}
